﻿
using KinonekoSoftware.Foundation.Platform;
using System.IO;
using DryIoc;
using KinonekoSoftware.Foundation.Platform;
using KinonekoSoftware.Platform;
using NLog;

namespace KinonekoSoftware.Platform.Windows
{

    public abstract partial class WindowsApplication : NativeApplication
    {
    }
}


#if WINDOWS


namespace KinonekoSoftware.Platform
{

    using Ookii.Dialogs.Wpf;
    using System.Windows.Threading;


    public abstract partial class NativeApplication : System.Windows.Application, IStorageService
    {
        public static string ImageFilter
        {
            get => LanguageManager.Language switch
            {
                LanguageArea.English => "Image File|*.png;*.jpg;*.bmp;*.jpeg",
                _                    => "图片文件|*.png;*.jpg;*.bmp;*.jpeg",
            };
        }

        public static string MusicFilter
        {
            get => LanguageManager.Language switch
            {
                LanguageArea.English => "Music File|*.mp3;*.wav",
                _                    => "音乐文件|*.mp3;*.wav",
            };
        }

        static string GetFormatFilter(FileFormat format)
        {
            return format switch
            {
                FileFormat.Music => MusicFilter,
                FileFormat.Image => ImageFilter,
                _                => "All File |*.*",
            };
        }

        public string GetSpecialFolder(SpecialFolder folder)
        {
            var uri = folder switch
            {
                SpecialFolder.Documents => Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                SpecialFolder.Downloads => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads",
                SpecialFolder.Music     => Environment.GetFolderPath(Environment.SpecialFolder.MyMusic),
                SpecialFolder.Video     => Environment.GetFolderPath(Environment.SpecialFolder.MyVideos),
                SpecialFolder.Picture   => Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),

                _ => Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            };

            return uri;
        }

        public string CheckDirectoryOrCreate(string dir)
        {
            if (string.IsNullOrEmpty(dir))
            {
                throw new ArgumentNullException(nameof(dir));
            }

            Directory.CreateDirectory(dir);

            return dir;
        }

        public async Task<Result<IOResult>> SingleFile(FileFormat format)
        {
            var opendlg = new VistaOpenFileDialog
            {
                Filter      = GetFormatFilter(format),
                Multiselect = false,
            };

            if (opendlg.ShowDialog() != true)
            {
                return Result<IOResult>.Failure;
            }

            var fileName = opendlg.FileName;
            var ext      = System.IO.Path.GetExtension(fileName);
            var name     = System.IO.Path.GetFileName(fileName);
            var buffer   = await System.IO.File.ReadAllBytesAsync(fileName);

            return Result<IOResult>.Success(new IOResult
            {
                Buffer    = buffer,
                Name      = name,
                Extension = ext,
                Path      = fileName,
            });
        }

        public async Task<Result<IList<IOResult>>> MultiFile(FileFormat format)
        {
            var opendlg = new VistaOpenFileDialog
            {
                Filter      = GetFormatFilter(format),
                Multiselect = true,
            };

            if (opendlg.ShowDialog() != true)
            {
                return Result<IList<IOResult>>.Failure;
            }

            var array = new List<IOResult>(8);

            foreach (var fileName in opendlg.FileNames)
            {
                var ext    = System.IO.Path.GetExtension(fileName);
                var name   = System.IO.Path.GetFileName(fileName);
                var buffer = await System.IO.File.ReadAllBytesAsync(fileName);
                var r = new IOResult
                {
                    Buffer    = buffer,
                    Name      = name,
                    Extension = ext,
                    Path      = fileName,
                };

                array.Add(r);
            }

            return Result<IList<IOResult>>.Success(array);
        }
        
        public static VistaSaveFileDialog Save(string filter, string defaultExt, string fileName = null)
        {
            return new VistaSaveFileDialog
            {
                FileName     = fileName,
                Filter       = filter,
                AddExtension = true,
                DefaultExt   = defaultExt,
            };
        }

        /// <summary>
        /// 创建Shell
        /// </summary>
        /// <returns>返回Shell</returns>
        protected abstract ShellCore CreateShell();


        #region Shells

        /// <summary>
        /// 初始化Shell
        /// </summary>
        /// <returns>返回Shell</returns>
        protected ShellCore SetupShell()
        {
            ShellCore shell;

            if (!Ioc.IsRegistered<ShellCore>())
            {

                //
                // 安装Shell
                shell = CreateShell();
                Ioc.Use<ShellCore>(shell);
                Ioc.Container
                   .UseInstance(
                                shell.GetType(),
                                shell,
                                IfAlreadyRegistered.AppendNewImplementation);
                Ioc.UseInstance <IViewService, IViewServiceAmbient>(shell);
            }
            else
            {
                //
                // 启动
                shell = Ioc.Get<ShellCore>();
            }

            //
            // 安装存储服务，提供
            Ioc.Use<IStorageService>(this);
            return shell;
        }


        
        
        
        private void InstallExceptionHandler()
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
            DispatcherUnhandledException               += OnUnhandledException;
        }
        
        private void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            if (_enableExceptionHandler)
            {
                Ioc.Get<ILogger>()
                   .Warn(e.Exception);
                e.Handled = true;
            }
        }
        
        private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (_enableExceptionHandler)
            {
                Ioc.Get<ILogger>()
                   .Error(e.ExceptionObject);
            }
        }

        protected virtual void OnFrameworkInitializationCompletedOverride()
        {

        }

        
        #endregion
    }

}

#endif